package cn.sczc.jh.client.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.sczc.jh.client.entity.EquipmentPos;
import cn.sczc.jh.client.entity.User;
import cn.sczc.jh.client.service.MQService;
import cn.sczc.jh.client.service.equipment.EquipmentPosService;
import cn.sczc.jh.client.util.WebUtil;
import cn.sczc.jh.client.vo.DeviceInfoVo;
import cn.sczc.jh.client.vo.SensorOnlineVo;
import cn.sczc.jh.client.websocket.WirelessDeviceWebSocket;
import cn.sczc.jh.client.websocket.vo.WebsocketMessageVo;

@RestController
@RequestMapping("/devices")
public class WirelessDeviceAPIController {
	@Autowired
	private MQService mqService;
	@Autowired
	private EquipmentPosService equipmentPosService;

	/**
	 * 打开设备
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/open")
	public ResponseEntity<?> deviceOpen(@PathVariable("id") String id, @RequestBody JSONObject jsonParam) {
		User user = (User) SecurityUtils.getSubject().getPrincipal();
		DeviceInfoVo di = new DeviceInfoVo();
		di.setData(jsonParam);
		di.setDeviceId(id);
		di.setTimestamp(System.currentTimeMillis());
		di.setTenantId(user.getTenantId().toString());
		di.setTeamId(user.getTeamId().toString());
		mqService.sendDeviceOpenMessage(id, JSON.toJSONString(di));
		return ResponseEntity.ok(di);
	}

	/**
	 * 关闭设备
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/close")
	public ResponseEntity<?> deviceClose(@PathVariable("id") String id) {
		DeviceInfoVo di = new DeviceInfoVo();
		di.setDeviceId(id);
		di.setTimestamp(System.currentTimeMillis());
		mqService.sendDeviceCloseMessage(id, JSON.toJSONString(di));
		return ResponseEntity.ok(di);
	}

	/**
	 * 关闭设备
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@GetMapping("/{id}/ports")
	public ResponseEntity<?> devicePortList(@PathVariable("id") String id) {
		DeviceInfoVo di = new DeviceInfoVo();
		di.setDeviceId(id);
		di.setTimestamp(System.currentTimeMillis());
		mqService.sendGetDevicePortMessage(id, JSON.toJSONString(di));
		return ResponseEntity.ok(di);
	}

	/**
	 * 指定设备上线
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/online")
	public ResponseEntity<?> deviceOnline(@PathVariable("id") String id) throws IOException {
		WebsocketMessageVo wm = new WebsocketMessageVo();
		wm.setType(WebsocketMessageVo.DEVICE_ONLINE_TYPE);
		wm.setData(id);
		WirelessDeviceWebSocket.sendMessage(wm, id);
		return ResponseEntity.ok().build();
	}

	@PostMapping("/{id}/sensor/{sensorAddress}/offline")
	public ResponseEntity<?> sensorOffline(@PathVariable("id") String id,
			@PathVariable("sensorAddress") String sensorAddress, @RequestBody SensorOnlineVo so) throws IOException {
		WebsocketMessageVo wm = new WebsocketMessageVo();
		wm.setType(WebsocketMessageVo.SENSOR_OFFLINE_TYPE);
		wm.setData(so);
		WirelessDeviceWebSocket.sendMessage(wm, id);
		return ResponseEntity.ok().build();
	}

	/**
	 * 指定设备下线
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/offline")
	public ResponseEntity<?> deviceOffline(@PathVariable("id") String id) throws IOException {
		WebsocketMessageVo wm = new WebsocketMessageVo();
		wm.setType(WebsocketMessageVo.DEVICE_OFFLINE_TYPE);
		wm.setData(id);
		WirelessDeviceWebSocket.sendMessage(wm, id);
		return ResponseEntity.ok().build();
	}

	/**
	 * 指定设备属性改变
	 * 
	 * @param id
	 * @param deviceInfo
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/info")
	public ResponseEntity<?> deviceInfo(@PathVariable("id") String id, @RequestBody Object deviceInfo)
			throws IOException {
		WebsocketMessageVo wm = new WebsocketMessageVo();
		wm.setType(WebsocketMessageVo.DEVICE_INFO_TYPE);
		wm.setData(deviceInfo);
		WirelessDeviceWebSocket.sendMessage(wm, id);
		return ResponseEntity.ok().build();
	}

	/**
	 * 指定设备属性改变
	 * 
	 * @param id
	 * @param deviceInfo
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/state")
	public ResponseEntity<?> deviceState(@PathVariable("id") String id, @RequestBody Object deviceInfo)
			throws IOException {
//		JSONObject object = JSON.parseObject(deviceInfo.toString());
//		String hexStr = object.getString("disappearState");
//		if (hexStr != null) {
//			String binaryStr = this.hexString2binaryString(this.reverseHex(hexStr));
//			String disappearState = new StringBuffer(binaryStr).reverse().toString();
//			if (disappearState != null && disappearState.length() > 0) {
//				for (int i = 0, len = disappearState.length(); i <= len; i++) {
//					if (i < 32 && String.valueOf(disappearState.charAt(i)).equals("1")) {
//						WebsocketMessageVo wm = new WebsocketMessageVo();
//						wm.setType(WebsocketMessageVo.SENSOR_OFFLINE_TYPE);
//						SensorOnlineVo so = new SensorOnlineVo();
//						so.setSensorAddress(i + 1 + "");
//						wm.setData(so);
//						WirelessDeviceWebSocket.sendMessage(wm, id);
//					}
//				}
//			}
//		}
		WebsocketMessageVo wm = new WebsocketMessageVo();
		wm.setType(WebsocketMessageVo.DEVICE_STATE_TYPE);
		wm.setData(deviceInfo);
		WirelessDeviceWebSocket.sendMessage(wm, id);
		return ResponseEntity.ok().build();
	}

	/**
	 * 传器器实时数据
	 * 
	 * @param id
	 * @param sersorInfo
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/sersors/")
	public ResponseEntity<?> sensorInfo(@PathVariable("id") String id, @RequestBody Object sersorInfo)
			throws IOException {
		User user = WebUtil.getCurUser();
		JSONObject object = JSON.parseObject(sersorInfo.toString());
		if (user != null) {
			Map<String, Object> params = new HashMap<>();
			params.put("equNo", id);
			params.put("equChannel", object.getString("address"));
			params.put("tenantId", user.getTenantId());
			EquipmentPos pos = equipmentPosService.getEquipmentPos(params);
			if (pos != null) {
				object.put("lon", pos.getEquLon());
				object.put("lat", pos.getEquLat());
				object.put("equName", pos.getEquName());
			}
		}
		object.put("equNo", id);
		WebsocketMessageVo wm = new WebsocketMessageVo();
		wm.setType(WebsocketMessageVo.SENSOR_INFO_TYPE);
		wm.setData(object);
		String json = JSON.toJSONString(wm);
		System.out.println("testyu" + json);
		WirelessDeviceWebSocket.sendMessage(wm, id);
		return ResponseEntity.ok().build();
	}

	/**
	 * 传器器实时数据
	 * 
	 * @param id
	 * @param sersorInfo
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/sersors/{address}/alarm")
	public ResponseEntity<?> sensorAlarm(@PathVariable("id") String id, @PathVariable("address") String address,
			@RequestBody Object sersorInfo) throws IOException {
		User user = WebUtil.getCurUser();
		JSONObject object = JSON.parseObject(sersorInfo.toString());
		if (user != null) {
			Map<String, Object> params = new HashMap<>();
			params.put("equNo", id);
			params.put("equChannel", object.getString("address"));
			params.put("tenantId", user.getTenantId());
			EquipmentPos pos = equipmentPosService.getEquipmentPos(params);
			if (pos != null) {
				object.put("lon", pos.getEquLon());
				object.put("lat", pos.getEquLat());
				object.put("equName", pos.getEquName());
			}
		}
		object.put("equNo", id);
		WebsocketMessageVo wm = new WebsocketMessageVo();
		wm.setType(WebsocketMessageVo.SENSOR_ALARM_TYPE);
		wm.setData(object);
		WirelessDeviceWebSocket.sendMessage(wm, id);
		return ResponseEntity.ok().build();
	}

	/**
	 * 发送设备端口
	 * 
	 * @param deviceId
	 * @param data
	 * @throws IOException
	 */
	@PostMapping("/{id}/ports")
	public ResponseEntity<?> devicePorts(@PathVariable("id") String id, @RequestBody Object ports) throws IOException {
		WebsocketMessageVo wm = new WebsocketMessageVo();
		wm.setType(WebsocketMessageVo.DEVICE_PORT_TYPE);
		wm.setData(ports);
		WirelessDeviceWebSocket.sendMessage(wm, id);
		return ResponseEntity.ok().build();
	}

	/**
	 * 获取云端推送状态
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@GetMapping("/{id}/cloudpush")
	public ResponseEntity<?> getCloudPushState(@PathVariable("id") String id) {
		User user = (User) SecurityUtils.getSubject().getPrincipal();
		DeviceInfoVo di = new DeviceInfoVo();
		di.setDeviceId(id);
		di.setTimestamp(System.currentTimeMillis());
		di.setTenantId(user.getTenantId().toString());
		di.setTeamId(user.getTeamId().toString());
		mqService.sendGetCloudPushMessage(id, JSON.toJSONString(di));
		return ResponseEntity.ok(di);
	}

	/**
	 * 发送云端推送状态
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/cloudpush")
	public ResponseEntity<?> cloudPushState(@PathVariable("id") String id, @RequestBody Object state)
			throws IOException {
		WebsocketMessageVo wm = new WebsocketMessageVo();
		wm.setType(WebsocketMessageVo.CLOUD_PUSH_TYPE);
		wm.setData(state);
		WirelessDeviceWebSocket.sendMessage(wm, id);
		return ResponseEntity.ok().build();
	}

	/**
	 * 开启云端推送
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/cloudpush/open")
	public ResponseEntity<?> openCloudPush(@PathVariable("id") String id) {
		User user = (User) SecurityUtils.getSubject().getPrincipal();
		DeviceInfoVo di = new DeviceInfoVo();
		di.setDeviceId(id);
		di.setTimestamp(System.currentTimeMillis());
		di.setTenantId(user.getTenantId().toString());
		di.setTeamId(user.getTeamId().toString());
		mqService.sendOpenCloudPushMessage(id, JSON.toJSONString(di));
		return ResponseEntity.ok(di);
	}

	/**
	 * 开启云端推送
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@PostMapping("/{id}/cloudpush/close")
	public ResponseEntity<?> closeCloudPush(@PathVariable("id") String id) {
		DeviceInfoVo di = new DeviceInfoVo();
		di.setDeviceId(id);
		di.setTimestamp(System.currentTimeMillis());
		mqService.sendCloseCloudPushMessage(id, JSON.toJSONString(di));
		return ResponseEntity.ok(di);
	}

	public String reverseHex(String hex) {
		final char[] charArray = hex.toCharArray();
		final int length = charArray.length;
		final int times = length / 2;
		for (int c1i = 0; c1i < times; c1i += 2) {
			final int c2i = c1i + 1;
			final char c1 = charArray[c1i];
			final char c2 = charArray[c2i];
			final int c3i = length - c1i - 2;
			final int c4i = length - c1i - 1;
			charArray[c1i] = charArray[c3i];
			charArray[c2i] = charArray[c4i];
			charArray[c3i] = c1;
			charArray[c4i] = c2;
		}
		return new String(charArray);
	}

	public String hexString2binaryString(String hexString) {
		if (hexString == null || hexString.length() % 2 != 0)
			return null;
		String bString = "", tmp;
		for (int i = 0; i < hexString.length(); i++) {
			tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16));
			bString += tmp.substring(tmp.length() - 4);
		}
		return bString;
	}

}